/*
 *@File pthread_cond.c
 *
 *@Date 2017-06-29 
 *
 *
 *@Description This is a demo for mutex lock  and cond usage 
 *  compile with command gcc -g -Wall pthread_cond.c -o cond -lpthread
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

int g_num = 0;
pthread_mutex_t g_mutex_lock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER; 


static void thread_fun1(void *arg)
{
    for (g_num = 1; g_num <= 9; g_num++)
    {
        pthread_mutex_lock(&g_mutex_lock);
        if (g_num %3 == 0)
        {
            pthread_cond_signal(&g_cond); // send a signal to notify thread2
        }
        else
        {
            printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, g_num);
        }

        pthread_mutex_unlock(&g_mutex_lock);
        sleep(1);
    }
}


static void thread_fun2(void *arg)
{
	while(g_num < 9)
	{
		pthread_mutex_lock(&g_mutex_lock);
		if (g_num % 3 != 0)
		{
			pthread_cond_wait(&g_cond, &g_mutex_lock); // wait signal from thread1	
		}
		
		printf("[%s:%d] %d\n", __FUNCTION__, __LINE__, g_num);	
		pthread_mutex_unlock(&g_mutex_lock);
		sleep(1);
	}
}


int main(int argc, char* argv[])
{
    pthread_t thread1 = 0;
    pthread_t thread2 = 0;
	int ret = -1;

	// create thread1
	ret = pthread_create(&thread1, NULL, (void *)thread_fun1, (void *)NULL);
	if (ret != 0)
	{
		pthread_mutex_destroy(&g_mutex_lock);
		pthread_cond_destroy(&g_cond);
		printf("[%s:%d] create thread1 failed\n", __FUNCTION__, __LINE__);
		return -1;	
	}

    // create pthread2
	ret = pthread_create(&thread2, NULL, (void *)thread_fun2, (void *)NULL);
	if (ret != 0)
	{
		pthread_mutex_destroy(&g_mutex_lock);
		pthread_cond_destroy(&g_cond);
		printf("[%s:%d] create thread2 failed\n", __FUNCTION__, __LINE__);
		return -1;	
	}

    // join thread
	pthread_join(thread2, NULL);
	pthread_join(thread1, NULL);

    // destroy mutex lock 
	pthread_mutex_destroy(&g_mutex_lock);
    // destroy cond
	pthread_cond_destroy(&g_cond);

    return 0;
}
